package com.aiti.lulian.ocr;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.aiti.base.core.exception.BusinessException;
import com.aiti.lulian.dto.OcrBusinessLicenseDto;
import com.aiti.lulian.dto.SysUpload;
import com.aiti.lulian.entity.OcrInfo;
import com.aiti.lulian.mapper.SysUploadMapper;
import com.aiti.lulian.service.OcrInfoService;
import com.aliyun.ocr_api20210707.Client;
import com.aliyun.ocr_api20210707.models.RecognizeBusinessLicenseRequest;
import com.aliyun.ocr_api20210707.models.RecognizeBusinessLicenseResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.file.Files;
import java.util.Date;

/**
 * description:
 * auth fcb
 * date 2025-06-07 14:00
 **/
@Service
@Slf4j
public class OcrService {

    @Autowired
    private Config ocrConfig;
    @Autowired
    private OcrInfoService ocrInfoService;
    @Autowired
    private SysUploadMapper sysUploadMapper;

    /**
     * 调用阿里云OCR服务识别营业执照
     * @param dto
     * @return @link { com.aiti.lulian.ocr.BusinessLicenseResult }
     * @throws BusinessException
     */
    public BusinessLicenseResult exeOcrBusinessLicenseService(OcrBusinessLicenseDto dto) {
        this.checkParam(dto);
        String fileId = this.getFileIdByUrl(dto.getFileUrl());
        if(fileId == null) {
            throw new BusinessException("未获取到文件id");
        }
        String fileFullPath = this.getFileFullPath(fileId);
        if(fileFullPath == null) {
            throw new BusinessException("未获取到文路径");
        }
        File imageFile = this.getFileByFullPath(fileFullPath);
        if(imageFile == null) {
            throw new BusinessException("未获取到文件");
        }
        Client client = this.getClient();
        if(client == null) {
            throw new BusinessException("获取阿里云OCR Client失败");
        }
        RecognizeBusinessLicenseResponse response = null;
        try {
            RecognizeBusinessLicenseRequest request = new RecognizeBusinessLicenseRequest();
            request.setBody(Files.newInputStream(imageFile.toPath()));
            response = client.recognizeBusinessLicense(request);
            log.info("阿里云OCR识别结果：{}", JSONUtil.toJsonStr(response));
        }
        catch (TeaException e) {
            log.error("阿里云OCR图片识别失败：{}", ExceptionUtil.stacktraceToString(e));
            ocrInfoService.save(this.buildErrorOcrInfo("", dto.getUnicode(), fileId, e.getMessage(), "business_license"));
            throw new BusinessException("图片内容识别失败：" + e.getMessage());
        }
        catch (Exception e) {
            log.error("OCR识别异常：{}", ExceptionUtil.stacktraceToString(e));
            ocrInfoService.save(this.buildErrorOcrInfo("", dto.getUnicode(), fileId, e.getMessage(), "business_license"));
            throw new BusinessException("调用OCR服务异常");
        }
        if(response == null) {
            log.error("阿里云OCR识别结果为空");
            throw new BusinessException("调用OCR服务异常");
        }
        if(response.body == null) {
            log.error("阿里云OCR识别结果为空");
            ocrInfoService.save(this.buildErrorOcrInfo("", dto.getUnicode(), fileId, "返回值body为空", "business_license"));
            throw new BusinessException("OCR识别结果为空");
        }
        OcrInfo businessLicense = this.buildSuccessOcrInfo(response.body.requestId, dto.getUnicode(), fileId, "business_license");
        ocrInfoService.save(businessLicense);
        return JSONUtil.toBean(response.body.data, BusinessLicenseResult.class);
    }

    private OcrInfo buildErrorOcrInfo(String requestId, String unicode, String fileId, String errorMsg, String type) {
        OcrInfo ocrInfo = new OcrInfo();
        ocrInfo.setBaseId(StrUtil.uuid());
        ocrInfo.setSuccess(0);
        ocrInfo.setErrorMsg(errorMsg);
        ocrInfo.setCreateTime(new Date());
        ocrInfo.setOcrType(type);
        ocrInfo.setRequestId(requestId);
        ocrInfo.setUnicode(unicode);
        ocrInfo.setFileId(fileId);
        return ocrInfo;
    }

    private OcrInfo buildSuccessOcrInfo(String requestId, String unicode, String fileId, String type) {
        OcrInfo ocrInfo = new OcrInfo();
        ocrInfo.setBaseId(StrUtil.uuid());
        ocrInfo.setSuccess(0);
        ocrInfo.setCreateTime(new Date());
        ocrInfo.setOcrType(type);
        ocrInfo.setRequestId(requestId);
        ocrInfo.setUnicode(unicode);
        ocrInfo.setFileId(fileId);
        return ocrInfo;
    }

    private void checkParam(OcrBusinessLicenseDto dto) {
        if(StrUtil.isEmpty(dto.getUnicode())) {
            throw new BusinessException("参数错误，统一社会信用代码/注册号不能为空");
        }
        if(StrUtil.isEmpty(dto.getFileUrl())) {
            throw new BusinessException("参数错误，营业执照不能为空");
        }
    }

    private File getFileByFullPath(String fullPath){
        if(StrUtil.isEmpty(fullPath)) {
            return null;
        }
        File file = new File(fullPath);
        if(!file.exists()) {
            return null;
        }
        return file;
    }

    /**
     * 获取文件绝对路径
     * @param fileId
     * @return
     */
    private String getFileFullPath(String fileId) {
        SysUpload sysUpload = sysUploadMapper.selectById(fileId);
        if(sysUpload == null) {
            return null;
        }
        return sysUpload.getBaseUrl();
    }

    /**
     * 提取文件id
     * @param url
     * @return
     */
    private String getFileIdByUrl(String url) {
        if(StrUtil.isEmpty(url)) {
            return null;
        }
        return url.substring(url.lastIndexOf("/") + 1);
    }

    private com.aliyun.ocr_api20210707.Client getClient() {
        try {
            return new com.aliyun.ocr_api20210707.Client(ocrConfig);
        }catch (Exception e) {
            log.error("获取阿里云OCR配置失败：{}", ExceptionUtil.stacktraceToString(e));
            return null;
        }
    }
}
